package tr.com.netgis.util;

import java.text.SimpleDateFormat;
import java.util.Collection;

import tr.com.netgis.NGApplication;
import tr.com.netgis.pojo.NGLocation;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.provider.Settings;
import android.telephony.TelephonyManager;

/**
 * 
 * @author NetGis
 * 
 */
public class Utility {

	/**
	 * Creates date formater with this pattern: yyyy-MM-dd HH:mm:ss
	 * 
	 * @return
	 */
	public static SimpleDateFormat createSimpleDateFormat() {
		SimpleDateFormat result = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		return result;
	}

	/**
	 * km 
	 * @param first
	 * @param second
	 * @return
	 */
	public static double distance (NGLocation from, NGLocation to) {
		if (from == null || to == null)
			return 0.0;
		return distance(from.getLat(), from.getLon(), to.getLat(), to.getLon(), 'K');
	}
	
	public static float speed (NGLocation from, NGLocation to) {
		float speed = 0;
		if (from != null && to != null) {
			double timeInterval = to.getTarihSaat() - from.getTarihSaat();
			double timeAsMinute = (double)(timeInterval/(1000 * 60));
			speed = (float) ((float)(60 * distance(from, to)) / timeAsMinute);			
		} 
		return speed;		
	}
	
	public static double distance(double lat1, double lon1, double lat2, double lon2,
			char unit) {
		double theta = lon1 - lon2;
		double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2))
				+ Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2))
				* Math.cos(deg2rad(theta));
		dist = Math.acos(dist);
		dist = rad2deg(dist);
		dist = dist * 60 * 1.1515;
		if (unit == 'K') {
			dist = dist * 1.609344;
		} else if (unit == 'N') {
			dist = dist * 0.8684;
		}
		return (dist);
	}

	/* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
	/* :: This function converts decimal degrees to radians : */
	/* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
	private static double deg2rad(double deg) {
		return (deg * Math.PI / 180.0);
	}

	/* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
	/* :: This function converts radians to decimal degrees : */
	/* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
	private static double rad2deg(double rad) {
		return (rad * 180.0 / Math.PI);
	}
	
	
	public static String TEST_DEVICE_ID = "355067046828422"; 
										   
	/**
	 * IMEI number<br>
	 * 
	 * @return emulatorse 355067046828422 (sinan android)
	 */
	public static String getDeviceId () {
		if (isEmulator()) {
			return TEST_DEVICE_ID;
		}
		if ("unknown".equals(Constants.DEVICE_ID)) {
			TelephonyManager telephonyManager = (TelephonyManager)NGApplication.getAppContext().getSystemService(Context.TELEPHONY_SERVICE);
			String deviceID = telephonyManager.getDeviceId();		
			Constants.DEVICE_ID = deviceID;			
		}
		return Constants.DEVICE_ID;
	}	
	
	public static boolean isEmulator () {
		return Build.PRODUCT.toLowerCase().indexOf("google_sdk") >= 0;
	}
	
	public static boolean isNotEmpty (String str){
		return str != null && !("".equals(str));
	}
	
	@SuppressWarnings("rawtypes")
	public static boolean isNotEmpty (Collection col){
		return col != null && col.size() > 0;
	}

	
	public static void killApp(boolean killSafely) {
        if (killSafely) {
            /*
             * Notify the system to finalize and collect all objects of the app
             * on exit so that the virtual machine running the app can be killed
             * by the system without causing issues. NOTE: If this is set to
             * true then the virtual machine will not be killed until all of its
             * threads have closed.
             */
            System.runFinalizersOnExit(true);

            /*
             * Force the system to close the app down completely instead of
             * retaining it in the background. The virtual machine that runs the
             * app will be killed. The app will be completely created as a new
             * app in a new virtual machine running in a new process if the user
             * starts the app again.
             */
            System.exit(0);
        } else {
            /*
             * Alternatively the process that runs the virtual machine could be
             * abruptly killed. This is the quickest way to remove the app from
             * the device but it could cause problems since resources will not
             * be finalized first. For example, all threads running under the
             * process will be abruptly killed when the process is abruptly
             * killed. If one of those threads was making multiple related
             * changes to the database, then it may have committed some of those
             * changes but not all of those changes when it was abruptly killed.
             */
            android.os.Process.killProcess(android.os.Process.myPid());
        }

    }	
	
	// Checks whether the GPS hardware is present in the device
	public static boolean haveGPS(Context ctx)
	{
	    PackageManager pmgr = ctx.getPackageManager();
	    boolean gotGPS = pmgr.hasSystemFeature("android.hardware.location.gps");
	    return gotGPS;
	}

	public static boolean isGPSEnabled(Context ctx) {
		String GpsProvider = Settings.Secure.getString(ctx.getContentResolver(),
				Settings.Secure.LOCATION_PROVIDERS_ALLOWED);

		if (GpsProvider.toLowerCase().indexOf("gps") >= 0 ) {
			return true;
		} else {
			return false;
		}
	}
	
	public static int toInt(String value){
		if (value == null || "".equals(value)) {
			return 0;
		}
		try {
			value = value.trim();
			return Integer.parseInt(value);
		} catch (Exception e) {
		}
		return 0;
	}
}
